#ifndef _GL_WINDOW_
#define _GL_WINDOW_

#include <QtOpenGLWidgets/QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QFile>
#include <QTextStream>
#include <QDir>
#include <QTimer>
#include <QMatrix4x4>
#include <QVector3D>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QKeyEvent>
#include "functions/textureUtil.hpp"
#include "functions/cameraCtrl.hpp"
#include "functions/CubeMesh.hpp"

// QOpenGLWidget 创建窗口; QOpenGLFunctions_3_3_Core OpenGl gl开头函数;
class AUVOpenGLWidget: public QOpenGLWidget, QOpenGLFunctions_3_3_Core {
    Q_OBJECT
public:
    explicit AUVOpenGLWidget( QWidget *parent = nullptr );
protected:
    virtual void initializeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();
    virtual void mousePressEvent( QMouseEvent* event ) override;
    virtual void mouseMoveEvent( QMouseEvent* event ) override;
    virtual void wheelEvent( QWheelEvent *event ) override;
    virtual void keyPressEvent( QKeyEvent* event) override;

private:
    QString loadShaderSource( const QString& filePath );
    GLuint compileShader( const QString& source, GLenum shaderType );
    GLuint createShaderProgram( const QString& vertexPath, const QString& fragPath );

    Camera _camera;
    // 摄像机更新函数
    void updateCamera();
    QMatrix4x4 getViewMatrix();
    QMatrix4x4 getProjectMatrix();

    GLuint _VAO, _VBO;
    GLuint _shaderProgram;
    GLuint _textureID;      // 纹理

    // uniform 位置; 
    GLuint _timeLocation;
    GLuint _transformLocation;
    GLuint _alphaLocation;
    GLuint _tintColorLocation;
    // 变换矩阵uniform
    GLuint _viewLocation;
    GLuint _projectionLocation;

    // 刷新频率控制Timer
    QTimer* _timer;

    // camera参数
    QVector3D _cameraPos;
    QVector3D _cameraFront;
    QVector3D _cameraUp;
    QVector3D _cameraRight;
    float _yaw;     // 偏航角 (左右)
    float _pitch;   // 俯仰角
    float _fov;
    //移动速度
    float _cameraSpeed;
    float _mouseSensitivity;
    // 鼠标控制
    QPoint _lastMousePos;
    bool _firstMouse;
    bool _mousePressed;


signals: 
public slots:
    void updateAnimation();
};

#endif
